# -*- coding: utf-8 -*-

################################################################################
## Form generated from reading UI file 'ACCOUNTING_PYSIDE6_CALC_THREE_AMOUNT_AGING_1_0MuGJVi.ui'
##
## Created by: Qt User Interface Compiler version 6.9.1
##
## WARNING! All changes made in this file will be lost when recompiling UI file!
################################################################################

from PyQt6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
    QMetaObject, QObject, QPoint, QRect,
    QSize, QTime, QUrl, Qt)
from PyQt6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
    QFont, QFontDatabase, QGradient, QIcon,
    QImage, QKeySequence, QLinearGradient, QPainter,
    QPalette, QPixmap, QRadialGradient, QTransform)
from PyQt6.QtWidgets import (QApplication, QDialog, QFrame, QGroupBox,
    QLabel, QLineEdit, QProgressBar, QPushButton,
    QSizePolicy, QWidget)

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        if not Dialog.objectName():
            Dialog.setObjectName(u"Dialog")
        Dialog.resize(411, 551)
        Dialog.setMinimumSize(QSize(411, 551))
        Dialog.setMaximumSize(QSize(411, 551))
        self.pushButton_1 = QPushButton(Dialog)
        self.pushButton_1.setObjectName(u"pushButton_1")
        self.pushButton_1.setGeometry(QRect(100, 500, 101, 31))
        self.pushButton_2 = QPushButton(Dialog)
        self.pushButton_2.setObjectName(u"pushButton_2")
        self.pushButton_2.setGeometry(QRect(210, 500, 101, 31))
        self.groupBox_1 = QGroupBox(Dialog)
        self.groupBox_1.setObjectName(u"groupBox_1")
        self.groupBox_1.setGeometry(QRect(20, 120, 371, 191))
        self.label_4 = QLabel(self.groupBox_1)
        self.label_4.setObjectName(u"label_4")
        self.label_4.setGeometry(QRect(20, 110, 331, 31))
        self.label_4.setAlignment(Qt.AlignmentFlag.AlignLeading|Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter)
        self.lineEdit_1 = QLineEdit(self.groupBox_1)
        self.lineEdit_1.setObjectName(u"lineEdit_1")
        self.lineEdit_1.setGeometry(QRect(190, 70, 161, 31))
        self.lineEdit_1.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.label_3 = QLabel(self.groupBox_1)
        self.label_3.setObjectName(u"label_3")
        self.label_3.setGeometry(QRect(190, 30, 161, 31))
        self.label_3.setFrameShape(QFrame.Shape.Box)
        self.label_3.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.label_1 = QLabel(self.groupBox_1)
        self.label_1.setObjectName(u"label_1")
        self.label_1.setGeometry(QRect(20, 30, 161, 31))
        self.label_1.setFrameShape(QFrame.Shape.Box)
        self.label_1.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.progressBar_1 = QProgressBar(self.groupBox_1)
        self.progressBar_1.setObjectName(u"progressBar_1")
        self.progressBar_1.setEnabled(True)
        self.progressBar_1.setGeometry(QRect(20, 140, 331, 31))
        self.progressBar_1.setValue(25)
        self.progressBar_1.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.progressBar_1.setTextVisible(True)
        self.label_2 = QLabel(self.groupBox_1)
        self.label_2.setObjectName(u"label_2")
        self.label_2.setGeometry(QRect(20, 70, 161, 31))
        self.label_2.setFrameShape(QFrame.Shape.Box)
        self.label_2.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.groupBox_2 = QGroupBox(Dialog)
        self.groupBox_2.setObjectName(u"groupBox_2")
        self.groupBox_2.setGeometry(QRect(20, 330, 371, 151))
        self.lineEdit_2 = QLineEdit(self.groupBox_2)
        self.lineEdit_2.setObjectName(u"lineEdit_2")
        self.lineEdit_2.setGeometry(QRect(190, 30, 161, 31))
        self.lineEdit_2.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.label_7 = QLabel(self.groupBox_2)
        self.label_7.setObjectName(u"label_7")
        self.label_7.setGeometry(QRect(20, 30, 161, 31))
        self.label_7.setFrameShape(QFrame.Shape.Box)
        self.label_7.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.label_8 = QLabel(self.groupBox_2)
        self.label_8.setObjectName(u"label_8")
        self.label_8.setGeometry(QRect(20, 70, 331, 31))
        self.label_8.setAlignment(Qt.AlignmentFlag.AlignLeading|Qt.AlignmentFlag.AlignLeft|Qt.AlignmentFlag.AlignVCenter)
        self.progressBar_2 = QProgressBar(self.groupBox_2)
        self.progressBar_2.setObjectName(u"progressBar_2")
        self.progressBar_2.setEnabled(True)
        self.progressBar_2.setGeometry(QRect(20, 100, 331, 31))
        self.progressBar_2.setValue(25)
        self.progressBar_2.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.progressBar_2.setTextVisible(True)
        self.groupBox_3 = QGroupBox(Dialog)
        self.groupBox_3.setObjectName(u"groupBox_3")
        self.groupBox_3.setGeometry(QRect(20, 20, 371, 81))
        self.label_5 = QLabel(self.groupBox_3)
        self.label_5.setObjectName(u"label_5")
        self.label_5.setGeometry(QRect(20, 30, 161, 31))
        self.label_5.setFrameShape(QFrame.Shape.Box)
        self.label_5.setAlignment(Qt.AlignmentFlag.AlignCenter)
        self.label_6 = QLabel(self.groupBox_3)
        self.label_6.setObjectName(u"label_6")
        self.label_6.setGeometry(QRect(190, 30, 161, 31))
        self.label_6.setFrameShape(QFrame.Shape.Box)
        self.label_6.setAlignment(Qt.AlignmentFlag.AlignCenter)

        self.retranslateUi(Dialog)

        QMetaObject.connectSlotsByName(Dialog)
    # setupUi

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Dialog", None))
        self.pushButton_1.setText(QCoreApplication.translate("Dialog", u"\u8ba1\u7b97", None))
        self.pushButton_2.setText(QCoreApplication.translate("Dialog", u"\u5173\u95ed", None))
        self.groupBox_1.setTitle(QCoreApplication.translate("Dialog", u"@ \u8ba1\u7b97\u914d\u7f6e - @ \u53d1\u751f\u989d\u5269\u4f59\u6570", None))
        self.label_4.setText(QCoreApplication.translate("Dialog", u"Preparing ...", None))
        self.lineEdit_1.setPlaceholderText(QCoreApplication.translate("Dialog", u"\u793a\u4f8b: 2025-08-31", None))
        self.label_3.setText(QCoreApplication.translate("Dialog", u"1970-01-01 00:00:00", None))
        self.label_1.setText(QCoreApplication.translate("Dialog", u"\u8d77\u59cb\u65f6\u95f4", None))
        self.label_2.setText(QCoreApplication.translate("Dialog", u"\u622a\u81f3\u65f6\u95f4", None))
        self.groupBox_2.setTitle(QCoreApplication.translate("Dialog", u"@ \u8ba1\u7b97\u914d\u7f6e - @ \u4e09\u91d1\u6570\u636e\u8868", None))
        self.lineEdit_2.setPlaceholderText(QCoreApplication.translate("Dialog", u"\u793a\u4f8b: 2025-08-31", None))
        self.label_7.setText(QCoreApplication.translate("Dialog", u"\u622a\u81f3\u65f6\u95f4", None))
        self.label_8.setText(QCoreApplication.translate("Dialog", u"Preparing ...", None))
        self.groupBox_3.setTitle(QCoreApplication.translate("Dialog", u"@ \u524d\u7f6e\u6570\u636e", None))
        self.label_5.setText(QCoreApplication.translate("Dialog", u"\u53d1\u751f\u989d\u7f13\u5b58", None))
        self.label_6.setText(QCoreApplication.translate("Dialog", u"Not Detected Cache", None))
    # retranslateUi

# #############################################################################################
# 新增 PyQt / PySide 对话框类 Class (继承自 QDialog) 以使用 Qt Designer / PySide 生成的 UI 代码
# #############################################################################################

import datetime
import math
import os
import sys
# ..................................................
WORKNG_PATH = sys.argv[1] if (len(sys.argv) >= 2) else ".."
CACHES_PATH = f"{WORKNG_PATH}{os.sep}SYSTEM{os.sep}SYSTEM_CACHES"
DOC_DB_PATH = f"{WORKNG_PATH}{os.sep}SYSTEM{os.sep}SYSTEM_DOCUMENTS_DATABASE"
# ..................................................
import openpyxl
import pandas
# ..................................................
from PyQt6.QtWidgets import QMessageBox
# ..................................................
from GF_PY3_SCRIPT_Accounting_First_In_First_Out import Accounting_First_In_First_Out

class Dialog_Calc_Three_Amount_Aging(QDialog):

    # PyQt / PySide 对话框类 Class (继承自 QDialog)

    def __init__(self, parent = None):

        super().__init__(parent)
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)

        # 连接信号和槽
        self.Setup_Connections()

        # ###############
        # 设置 GUI 默认值
        # ###############

        if (os.path.exists(f"{CACHES_PATH}{os.sep}cache_for_accounting_contract_occur.csv") == True):
            df = pandas.read_csv(f"{CACHES_PATH}{os.sep}cache_for_accounting_contract_occur.csv", usecols=["时间"], dtype = str)
            df = df[df["时间"].isna() == False]
            df["时间"] = pandas.to_datetime(df["时间"], format = "mixed")
            # ......................................
            metrics = self.ui.label_6.fontMetrics()
            elided_text = metrics.elidedText(f"{CACHES_PATH}{os.sep}cache_for_accounting_contract_occur.csv", Qt.TextElideMode.ElideMiddle, self.ui.label_6.width())
            # ......................................
            self.ui.label_6.setText(elided_text)
            self.ui.label_3.setText(f"{df['时间'].max()}")
        # ..........................................
        self.ui.progressBar_1.setValue(0)  # 设置默认值: 进度条初始化为 0.0
        self.ui.progressBar_2.setValue(0)  # 设置默认值: 进度条初始化为 0.0

    def Setup_Connections(self):

        """ 连接所有信号和槽 """

        # 连接按钮
        self.ui.pushButton_1.clicked.connect(self.DIY_on_pushButton_1_clicked)
        self.ui.pushButton_2.clicked.connect(self.DIY_on_pushButton_2_clicked)

    def DIY_on_pushButton_1_clicked(self):

        df = pandas.read_csv(f"{CACHES_PATH}{os.sep}cache_for_accounting_contract_occur.csv", dtype = str)
        # ..........................................
        df = df[df["时间"].isna() == False]
        # ..........................................
        df["时间"] = pandas.to_datetime(df["时间"], format = "mixed")
        # ..........................................
        df["发生额"] = df["发生额"].str.replace(',', '')
        df["发生额"] = df["发生额"].fillna(value = '0')
        df["发生额"] = df["发生额"].astype("float64")
        # ..........................................
        df["借贷标志"] = df["发生额"].apply(lambda x: "借"     if (x >= 0) else "贷")
        df["借方"    ] = df["发生额"].apply(lambda x: x        if (x >= 0) else 0)
        df["贷方"    ] = df["发生额"].apply(lambda x: x * (-1) if (x  < 0) else 0)
        # ..........................................
        # 分配 "Row Number"
        df = df.sort_values(["WBS编码", "时间"], ascending = [True, True])
        df["ROW_NUM"] = df[["WBS编码", "时间"]].groupby("WBS编码", as_index = False).rank(method = "first")
        df["ROW_NUM"] = df["ROW_NUM"].astype("int64")
        # ..........................................
        # 创建 "发生额剩余数"
        df["发生额剩余数"] = df["发生额"]
        # ..........................................
        # 创建 "ID"
        df["ID"] = df.index + 1

        # ---------------------------------------
        # Pandas 处理过程: 按 "截至日期" 筛选数据
        # ---------------------------------------

        if (self.ui.lineEdit_1.text() != ''):

            df = df[df["时间"] <= pandas.to_datetime(self.ui.lineEdit_1.text(), format = "mixed")]

        # ----------------------------------------------------------
        # Pandas 处理过程: 按 "WBS 编码" 计算发生额剩余数 (先进先出)
        # ----------------------------------------------------------

        List_for_DataFrame = []
        Total = df["WBS编码"].drop_duplicates().count()
        Count = 1
        # ..........................................
        for WBS_CODE in df["WBS编码"].drop_duplicates():
            # 开始循环
            self.ui.label_4.setText(f"""PROCESSING: {WBS_CODE} ({Count}/{Total})""")  # Qt 代码: 将过程输出到 self.ui.label_4 对象
            self.ui.progressBar_1.setValue(math.floor(Count / Total * 100))           # Qt 代码: 更新进度条
            QApplication.processEvents()                                              # Qt 代码: 处理事件 (立即响应)
            # ......................................
            TEMP = df[df["WBS编码"] == WBS_CODE].reset_index(drop = True).copy()
            DICT_RESULT = Accounting_First_In_First_Out(TEMP)
            DICT_RESULT["剩余数"]["WBS编码"] = WBS_CODE
            DICT_RESULT["剩余数"] = DICT_RESULT["剩余数"][["ROW_NUM", "ID", "时间", "WBS编码", "借方", "贷方", "借贷标志", "发生额", "发生额剩余数"]]
            # ......................................
            # WARNING: "输入 / 输出" 行数对照
            Input_Rows_Number = len(df[df["WBS编码"] == WBS_CODE])
            Output_Rows_Number = len(DICT_RESULT["剩余数"])
            if (Input_Rows_Number != Output_Rows_Number):
                print(f"""[WARNING] 输入行数: {Input_Rows_Number} / 输出行数: {Output_Rows_Number}""")
            # ......................................
            List_for_DataFrame.append(DICT_RESULT["剩余数"])
            Count = Count + 1
        # ..........................................
        DataFrame_for_FIFO = pandas.concat(List_for_DataFrame, ignore_index = True)

        # -----------------------------------------------------------------------
        # Pandas 处理过程: 保存中间数据 "accounting_contract_occur_remaining.csv"
        # -----------------------------------------------------------------------

        DataFrame_for_FIFO.to_csv(f"{CACHES_PATH}{os.sep}cache_for_accounting_contract_occur_remaining.csv", index = False)

        # -----------------------------
        # Pandas 处理过程: 连接附加信息
        # -----------------------------

        Df_Aging = pandas.merge(left = DataFrame_for_FIFO, right = df[["ID", "往来单位名称"]], how = "left", on = "ID")
        Df_BpInf = pandas.read_excel(f"{DOC_DB_PATH}{os.sep}business_partner_infomation_往来单位信息.xlsx", sheet_name = 0, dtype = str)
        Df_BpInf = Df_BpInf[["往来单位名称", "所属三金数据项"]]
        Df_Aging = pandas.merge(left = Df_Aging, right = Df_BpInf, how = "left", on = "往来单位名称")

        # ------------------------------------------------
        # Pandas 处理过程: 筛选 "资产/负债" (只筛选出资产)
        # ------------------------------------------------

        Df_Aging = Df_Aging[Df_Aging["发生额剩余数"] >= 0]

        self.ui.label_8.setText(f"""PROCESSING: Filtering 资产""")
        self.ui.progressBar_2.setValue(50)
        QApplication.processEvents()

        # ------------------------------------------------------
        # Pandas 处理过程: 计算 "发生额剩余数" 帐龄 (三金数据项)
        # ------------------------------------------------------

        Current_Time = datetime.datetime.now() if (self.ui.lineEdit_2.text() == '') else self.ui.lineEdit_2.text()
        Current_Time = pandas.to_datetime(Current_Time, format = "mixed")
        # ..........................................
        Df_Aging["TimeDelta"] = Current_Time - Df_Aging["时间"]
        # ..........................................
        for i in Df_Aging.index:
            TimeDelta = Df_Aging.loc[i, "TimeDelta"]
            Days = TimeDelta.days
            if (                   Days <= 364):
                Df_Aging.loc[i, "帐龄"] = "1年以内(不含1年)"
            if (            364 <  Days and Days <= 364 + 365 + 365):
                Df_Aging.loc[i, "帐龄"] = "1-3年(不含3年)"
            if (364 + 365 + 365 <  Days):
                Df_Aging.loc[i, "帐龄"] = "3年及以上"

        # -----------------------------------------------------------------
        # Pandas 处理过程: 保存中间数据 "accounting_three_amount_aging.csv"
        # -----------------------------------------------------------------

        Df_Aging.to_csv(f"{CACHES_PATH}{os.sep}cache_for_accounting_three_amount_aging.csv", index = False)

        # --------------------------------------------------------------------------------------------
        # Pandas 处理过程: 创建透视表, "所属三金数据项" 作为行索引, "帐龄" 作为列, "发生额剩余数" 求和
        # --------------------------------------------------------------------------------------------

        Df_Three = Df_Aging.pivot_table(values = '发生额剩余数', index = '所属三金数据项', columns = '帐龄', aggfunc = 'sum')

        # ----------------------------------------------------------------
        # OpenPyXL 处理过程: 按照 Excel 模板填制 "三金数据" (合同帐龄部分)
        # ----------------------------------------------------------------

        wb = openpyxl.load_workbook(f"{DOC_DB_PATH}{os.sep}CPECC西南分公司_1640ZZ0001_三金数据模板_20250801.xlsx")
        ws = wb["1640ZZ0001"]  # 通过 Sheet 名字选择工作表
        Df_Three["1年以内(不含1年)"] = Df_Three["1年以内(不含1年)"].fillna(value = 0)
        Df_Three["1-3年(不含3年)"  ] = Df_Three["1-3年(不含3年)"  ].fillna(value = 0)
        Df_Three["3年及以上"       ] = Df_Three["3年及以上"       ].fillna(value = 0)
        Df_Three["合同资产余额"    ] = Df_Three["1年以内(不含1年)"] + Df_Three["1-3年(不含3年)"] + Df_Three["3年及以上"]
        Df_Three = Df_Three.rename(columns = {"合同资产余额":     "AP",
                                              "1年以内(不含1年)": "AQ",
                                              "1-3年(不含3年)":   "AR",
                                              "3年及以上":        "AS"})
        LIST_Index = Df_Three.index.values.tolist()
        for i in range(0, len(LIST_Index), 1):
            if (LIST_Index[i] == "勘探与生产"): LIST_Index[i] = 9
            if (LIST_Index[i] == "天然气销售"): LIST_Index[i] = 10
            if (LIST_Index[i] == "中油技服"  ): LIST_Index[i] = 12
            if (LIST_Index[i] == "炼化公司"  ): LIST_Index[i] = 13
            if (LIST_Index[i] == "其中: 1.1中油工程股份与中油工程股份(地区公司间)"): LIST_Index[i] = 17
            if (LIST_Index[i] == "1.2成员企业内部(地区公司内部)"): LIST_Index[i] = 18
            if (LIST_Index[i] == "集团内 - 其他单位"): LIST_Index[i] = 25
            if (LIST_Index[i] == "国家管网"  ): LIST_Index[i] = 27
            if (LIST_Index[i] == "集团外 - 其他单位"): LIST_Index[i] = 29
        Df_Three.index = LIST_Index

        for RowIdx in Df_Three.index:
            for ColIdx in Df_Three.columns:
                ws[f"{ColIdx}{RowIdx}"].value = Df_Three.loc[RowIdx, ColIdx]

        wb.save(f"{CACHES_PATH}{os.sep}cache_CPECC西南分公司_1640ZZ0001_三金数据_合同帐龄部分.xlsx")

        self.ui.label_8.setText(f"""PROCESSING: Calculating 帐龄""")
        self.ui.progressBar_2.setValue(100)
        QApplication.processEvents()

        # -----------------
        # COMMAND LINE 输出
        # -----------------

        sys.stdout.write(f"{CACHES_PATH}{os.sep}cache_CPECC西南分公司_1640ZZ0001_三金数据_合同帐龄部分.xlsx")

        # -----------------------
        # PyQt6 Dialog 关闭对话框
        # -----------------------

        self.close()

    def DIY_on_pushButton_2_clicked(self):

        self.reject()

if __name__ == "__main__":

    app = QApplication(sys.argv)

    # 设置应用程序样式
    app.setStyle('Fusion')

    # 创建并显示对话框
    dialog = Dialog_Calc_Three_Amount_Aging()
    dialog.show()

    sys.exit(app.exec())
